# -*- coding: utf-8 -*-
import logging
import threading
from zc_core.client.mongo_client import Mongo

logger = logging.getLogger('CatalogHelper')


class CatalogHelper(object):
    _instance_lock = threading.Lock()
    _biz_inited = False

    def __new__(cls, *args, **kwargs):
        if not hasattr(CatalogHelper, "_instance"):
            with CatalogHelper._instance_lock:
                if not hasattr(CatalogHelper, "_instance"):
                    CatalogHelper._instance = object.__new__(cls)
        return CatalogHelper._instance

    def __init__(self):
        if not self._biz_inited:
            self._biz_inited = True
            self.mongo = Mongo()
            coll = self.mongo.get_collection('catalog_pool')
            if coll:
                sorted_pool = coll.find().sort("level")
                if sorted_pool:
                    self._build_plain_cat(sorted_pool)

    def _build_plain_cat(self, pool):
        self.cat1_map = dict()
        self.cat2_map = dict()
        self.cat3_map = dict()
        self.cat1_name_map = dict()
        self.cat2_name_map = dict()
        self.cat3_name_map = dict()
        for row in pool:
            if row.get('level') == 1:
                self.cat1_map[row.get('_id')] = {
                    'catalog1Id': row.get('_id'),
                    'catalog1Name': row.get('catalogName'),
                }
                self.cat1_name_map[row.get('catalogName')] = {
                    'catalog1Id': row.get('_id'),
                    'catalog1Name': row.get('catalogName'),
                }
            if row.get('level') == 2:
                cat1 = self.cat1_map.get(str(row.get('parentId')), {})
                self.cat2_map[row.get('_id')] = {
                    'catalog1Id': cat1.get('catalog1Id'),
                    'catalog1Name': cat1.get('catalog1Name'),
                    'catalog2Id': row.get('_id'),
                    'catalog2Name': row.get('catalogName'),
                }
                self.cat2_name_map[row.get('catalogName')] = {
                    'catalog1Id': cat1.get('catalog1Id'),
                    'catalog1Name': cat1.get('catalog1Name'),
                    'catalog2Id': row.get('_id'),
                    'catalog2Name': row.get('catalogName'),
                }
            if row.get('level') == 3:
                cat2 = self.cat2_map.get(str(row.get('parentId')), {})
                self.cat3_map[row.get('_id')] = {
                    'catalog1Id': cat2.get('catalog1Id'),
                    'catalog1Name': cat2.get('catalog1Name'),
                    'catalog2Id': cat2.get('catalog2Id'),
                    'catalog2Name': cat2.get('catalog2Name'),
                    'catalog3Id': row.get('_id'),
                    'catalog3Name': row.get('catalogName'),
                }
                self.cat3_name_map[row.get('catalogName')] = {
                    'catalog1Id': cat2.get('catalog1Id'),
                    'catalog1Name': cat2.get('catalog1Name'),
                    'catalog2Id': cat2.get('catalog2Id'),
                    'catalog2Name': cat2.get('catalog2Name'),
                    'catalog3Id': row.get('_id'),
                    'catalog3Name': row.get('catalogName'),
                }

    def fill(self, item):
        if item.get('catalog3Id') and self.cat3_map and \
                (not item.get('catalog1Id') or not item.get('catalog1Name')
                 or not item.get('catalog2Id') or not item.get('catalog2Name')):
            cat3 = self.cat3_map.get(item.get('catalog3Id'))
            if cat3:
                # 一级分类编号
                item['catalog1Id'] = cat3.get('catalog1Id')
                # 一级分类名称
                item['catalog1Name'] = cat3.get('catalog1Name')
                # 二级分类编号
                item['catalog2Id'] = cat3.get('catalog2Id')
                # 二级分类名称
                item['catalog2Name'] = cat3.get('catalog2Name')
                # 三级分类名称
                item['catalog3Name'] = cat3.get('catalog3Name')
            else:
                logger.error('三级分类不存在：catalog3Id=%s' % item.get('catalog3Id'))
        elif item.get('catalog3Name') and self.cat3_map and \
                (not item.get('catalog1Id') or not item.get('catalog1Name')
                 or not item.get('catalog2Id') or not item.get('catalog2Name')):
            cat3 = self.cat3_name_map.get(item.get('catalog3Name'))
            if cat3:
                # 一级分类编号
                item['catalog1Id'] = cat3.get('catalog1Id')
                # 一级分类名称
                item['catalog1Name'] = cat3.get('catalog1Name')
                # 二级分类编号
                item['catalog2Id'] = cat3.get('catalog2Id')
                # 二级分类名称
                item['catalog2Name'] = cat3.get('catalog2Name')
                # 三级分类编号
                item['catalog3Id'] = cat3.get('catalog3Id')
            else:
                logger.error('三级分类不存在：catalog3Name=%s' % item.get('catalog3Name'))
        elif item.get('catalog2Id') and self.cat2_map and \
                (not item.get('catalog1Id') or not item.get('catalog1Name')):
            cat2 = self.cat2_map.get(item.get('catalog2Id'))
            if cat2:
                # 一级分类编号
                item['catalog1Id'] = cat2.get('catalog1Id')
                # 一级分类名称
                item['catalog1Name'] = cat2.get('catalog1Name')
                # 二级分类名称
                item['catalog2Name'] = cat2.get('catalog2Name')
            else:
                logger.error('二级分类不存在：catalog2Id=%s' % item.get('catalog2Id'))
        elif item.get('catalog2Name') and self.cat2_map and \
                (not item.get('catalog1Id') or not item.get('catalog1Name')):
            cat2 = self.cat2_name_map.get(item.get('catalog2Name'))
            if cat2:
                # 一级分类编号
                item['catalog1Id'] = cat2.get('catalog1Id')
                # 一级分类名称
                item['catalog1Name'] = cat2.get('catalog1Name')
                # 二级分类编号
                item['catalog2Id'] = cat2.get('catalog2Id')
            else:
                logger.error('二级分类不存在：catalog2Name=%s' % item.get('catalog2Name'))

        return item

    # 关闭链接
    def close(self):
        self.mongo.close()
